/*-----------------------------------------
file name  : fxp_addsub.v
created    : 2025/04/26 14:22:23
modified   : 2025-04-26 14:58:36
description: addition and subtraction
notes      : 
author     : yyrwkk
-----------------------------------------*/
module fxp_addsub # (
    parameter WIIA = 8    ,
    parameter WIFA = 8    ,
    parameter WIIB = 8    ,
    parameter WIFB = 8    ,
    parameter WOI  = 8    ,
    parameter WOF  = 8    ,
    parameter ROUND= 1    
)(
    input  [WIIA+WIFA-1:0] ina     ,
    input  [WIIB+WIFB-1:0] inb     ,
    input                  sub     , // 0=add, 1=sub
    output [WOI +WOF -1:0] out     ,
    output                 overflow
);

localparam WIIBE = WIIB + 1                 ;
localparam WII   = WIIA>WIIBE ? WIIA : WIIBE;
localparam WIF   = WIFA>WIFB  ? WIFA : WIFB ;
localparam WRI   = WII + 1                  ;
localparam WRF   = WIF                      ;

wire [WIIBE+WIFB-1:0] inbe;
wire [  WII+ WIF-1:0] inaz;
wire [  WII+ WIF-1:0] inbz;
wire [WIIBE+WIFB-1:0] inbv;
assign inbv = sub ? (~inbe)+ 1'b1 : inbe;

wire [WRI+WRF-1:0] res;
assign res = $signed(inaz) + $signed(inbz);

// one bit signed extends
// fxp_zoom # (
//     .WII      ( WIIB     ),
//     .WIF      ( WIFB     ),
//     .WOI      ( WIIBE    ),
//     .WOF      ( WIFB     ),
//     .ROUND    ( 0        )
// ) inb_extend (
//     .in       ( inb      ),
//     .out      ( inbe     ),
//     .overflow (          )
// );
assign inbe = {inb[WIIB+WIFB-1],inb};

fxp_zoom # (
    .WII      ( WIIA     ),
    .WIF      ( WIFA     ),
    .WOI      ( WII      ),
    .WOF      ( WIF      ),
    .ROUND    ( 0        )
) ina_zoom (
    .in       ( ina      ),
    .out      ( inaz     ),
    .overflow (          )
);

fxp_zoom # (
    .WII      ( WIIBE    ),
    .WIF      ( WIFB     ),
    .WOI      ( WII      ),
    .WOF      ( WIF      ),
    .ROUND    ( 0        )
) inb_zoom (
    .in       ( inbv     ),
    .out      ( inbz     ),
    .overflow (          )
);

fxp_zoom # (
    .WII      ( WRI      ),
    .WIF      ( WRF      ),
    .WOI      ( WOI      ),
    .WOF      ( WOF      ),
    .ROUND    ( ROUND    )
) res_zoom (
    .in       ( res      ),
    .out      ( out      ),
    .overflow ( overflow )
);

endmodule
